package it.unicam.ids.pvm.data.mysql;

import it.unicam.ids.pvm.data.AnnuncioDAO;
import it.unicam.ids.pvm.data.DAOException;
import it.unicam.ids.pvm.distributore.Annuncio;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * La classe rappresenta un'implementazione dell'interfaccia 
 * AnnuncioDAO, relativa al DBMS MySQL.
 * @author Luca Iachini, Valerio Iachini, Alessandro Cardenà
 *
 */
public class MySQLAnnuncioDAO implements AnnuncioDAO {

	final String sqlDelete = "DELETE FROM annuncio WHERE etichetta = ?";
	final String sqlInsert = "INSERT INTO annuncio (descrizione) VALUES (?)";
	final String sqlUpdate = "UPDATE annuncio SET descrizione = ? WHERE id = ?";
	final String sqlSelectAll = "SELECT id,descrizione FROM annuncio";
	final String sqlSelectAnnuncio = "SELECT * FROM annuncio WHERE id = ?";
	final String sqlCount = "SELECT COUNT(*) FROM annuncio";

	@Override
	public void delete(Annuncio annuncio) throws DAOException {
		Connection conn = MySQLDAOFactory.createConnection();
		PreparedStatement ps = null;
		boolean error = false;
		try {
			ps = conn.prepareStatement(sqlDelete);
			ps.setInt(1, annuncio.getId());
			ps.executeUpdate();
		} catch (SQLException e) {
			error = true;
		} finally {
			if (ps != null) {
				try {
					ps.close();
				} catch (SQLException e) {
					error = true;
				}
			}
			if (error)
				throw new DAOException(
						"Errore nella cancellazione dell'annuncio.");
		}

	}

	@Override
	public Annuncio[] findAllAnnunci() throws DAOException {
		Annuncio[] annunci = null;
		PreparedStatement ps = null;
		boolean error = false;
		Connection conn = MySQLDAOFactory.createConnection();
		ResultSet rs = null;
		try {
			ps = conn.prepareStatement(sqlSelectAll);
			rs = ps.executeQuery();
			annunci = new Annuncio[getRowCount()];
			for (int i = 0; rs.next(); i++) {
				int id = rs.getInt("id");
				String descrizione = rs.getString("descrizione");
				annunci[i] = new Annuncio(id, descrizione);
			}
		} catch (Exception e) {
			error = true;
		} finally {
			if (ps != null)
				try {
					ps.close();
				} catch (SQLException e) {
					error = true;
				}
			if (rs != null)
				try {
					rs.close();
				} catch (SQLException e) {
					error = true;
				}
			if (error)
				throw new DAOException(
						"Errore nel recupero dei dati riguardanti gli annunci.");
		}
		return annunci;
	}

	@Override
	public Annuncio findById(int idAnnuncio) throws DAOException {
		Annuncio annuncio = null;
		PreparedStatement ps = null;
		boolean error = false;
		Connection conn = MySQLDAOFactory.createConnection();
		ResultSet rs = null;
		try {
			ps = conn.prepareStatement(sqlSelectAll);
			rs = ps.executeQuery();
			rs.next();
			int id = rs.getInt("id");
			String descrizione = rs.getString("descrizione");
			annuncio = new Annuncio(id, descrizione);
		} catch (Exception e) {
			error = true;
		} finally {
			if (ps != null)
				try {
					ps.close();
				} catch (SQLException e) {
					error = true;
				}
			if (rs != null)
				try {
					rs.close();
				} catch (SQLException e) {
					error = true;
				}
			if (error)
				throw new DAOException(
						"Errore nel recupero dei dati riguardanti l'annuncio.");
		}
		return annuncio;
	}
	@Override
	public void insert(Annuncio annuncio) throws DAOException {
		Connection conn = MySQLDAOFactory.createConnection();
		PreparedStatement ps = null;
		boolean error = false;
		try {
			ps = conn.prepareStatement(sqlInsert);
			ps.setInt(1, annuncio.getId());
			ps.setString(2, annuncio.getDescrizione());
			ps.executeUpdate();
		} catch (SQLException e) {
			error = true;
		} finally {
			if (ps != null) {
				try {
					ps.close();
				} catch (SQLException e) {
					error = true;
				}
			}
			if (error)
				throw new DAOException("Errore nell'inserimento dell'annuncio.");
		}

	}

	@Override
	public void update(Annuncio annuncio) throws DAOException {
		Connection conn = MySQLDAOFactory.createConnection();
		PreparedStatement ps = null;
		boolean error = false;
		try {
			ps = conn.prepareStatement(sqlUpdate);
			ps.setInt(1, annuncio.getId());
			ps.setString(2, annuncio.getDescrizione());
			ps.executeUpdate();
		} catch (SQLException e) {
			error = true;
		} finally {
			if (ps != null) {
				try {
					ps.close();
				} catch (SQLException e) {
					error = true;
				}
			}
			if (error)
				throw new DAOException(
						"Errore nell'aggiornamento dell'annuncio.");
		}
	}

	/**
	 * Il metodo restituisce il numero delle righe della 
	 * tabella relativa agli annunci del database.
	 * @return count nuomero di righe.
	 * @throws SQLException
	 * @throws DAOException messaggio d'errore relativo 
	 * 							al conteggio delle righe.
	 */
	
	private int getRowCount() throws SQLException, DAOException {
		int count = 0;
		Connection conn = MySQLDAOFactory.createConnection();
		PreparedStatement ps = null;
		ResultSet rs = null;
		boolean error = false;
		try {
			ps = conn.prepareStatement(sqlCount);
			rs = ps.executeQuery();
			rs.next();
			count = rs.getInt(1);
		} catch (SQLException e) {
			error = true;
		} finally {
			if (ps != null) {
				try {
					ps.close();
				} catch (SQLException e) {
					error = true;
				}
				if (rs != null)
					rs.close();
			}
			if (error)
				throw new DAOException(
						"Errore nell'aggiornamento della casella");
		}
		return count;
	}

}
